package io.github.uicdb.et.recipe;

import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.github.uicdb.et.ElementalTheory;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.HolderLookup;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.*;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;

@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@RequiredArgsConstructor
@Getter
public class ExtractRecipe implements Recipe<RecipeInput> {
    public static final MapCodec<ExtractRecipe> CODEC = RecordCodecBuilder.mapCodec(i -> i.group(
            Ingredient.CODEC.fieldOf("input").forGetter(ExtractRecipe::getIngredient),
            ElementRecipePart.CODEC.listOf().fieldOf("result").forGetter(ExtractRecipe::getResult)
    ).apply(i, ExtractRecipe::new));
    public static final StreamCodec<RegistryFriendlyByteBuf, ExtractRecipe> STREAM_CODEC = StreamCodec.composite(
            Ingredient.CONTENTS_STREAM_CODEC,
            ExtractRecipe::getIngredient,
            ElementRecipePart.STREAM_CODEC.apply(ByteBufCodecs.list()),
            ExtractRecipe::getResult,
            ExtractRecipe::new
    );
    public static final RecipeType<ExtractRecipe> TYPE = RecipeType.simple(ResourceLocation.fromNamespaceAndPath(ElementalTheory.MODID, "extract_recipe"));

    final Ingredient ingredient;
    final List<ElementRecipePart> result;

    @Override
    public boolean matches(RecipeInput extractRecipeInput, Level level) {
        return ingredient.test(extractRecipeInput.getItem(0));
    }

    @Override
    public ItemStack assemble(RecipeInput extractRecipeInput, HolderLookup.Provider provider) {
        return extractRecipeInput.getItem(0).getCraftingRemainingItem();
    }

    @Override
    public boolean canCraftInDimensions(int i, int i1) {
        return true;
    }

    @Override
    public ItemStack getResultItem(HolderLookup.Provider provider) {
        return ItemStack.EMPTY;
    }

    @Override
    public RecipeSerializer<?> getSerializer() {
        return Serializer.INSTANCE;
    }

    @Override
    public RecipeType<?> getType() {
        return TYPE;
    }
    public static class Serializer implements RecipeSerializer<ExtractRecipe> {
        public static final Serializer INSTANCE = new Serializer();

        public @NotNull MapCodec<ExtractRecipe> codec() {
            return ExtractRecipe.CODEC;
        }

        public @NotNull StreamCodec<RegistryFriendlyByteBuf, ExtractRecipe> streamCodec() {
            return ExtractRecipe.STREAM_CODEC;
        }

    }
}
